package krao.data;

import java.util.ArrayList;

public class TBox {
	public ArrayList<TBoxClass> classes;
	public ArrayList<TBoxProperty> properties;

	public TBox() {
		classes = new ArrayList<TBoxClass>();
		properties = new ArrayList<TBoxProperty>();
	}

	/**
	 * Adds a class to the tbox
	 * 
	 * @param newClassName
	 *            name of the class to be added
	 * @return added class if there was no class with this name, otherwise
	 *         existing class with this name.
	 */
	public TBoxClass addClass(String newClassName) {
		if (!containsClass(newClassName)) {
			TBoxClass newClass = new TBoxClass(newClassName);
			classes.add(newClass);
			return newClass;
		} else {
			return getClass(newClassName);
		}
	}

	/**
	 * Adds a property to the tbox
	 * 
	 * @param newPropName
	 *            name of the property to be added
	 * @return added property if there was no property with this name, otherwise
	 *         existing property with this name.
	 */
	public TBoxProperty addProperty(String newPropName) {
		if (!containsProperty(newPropName)) {
			TBoxProperty newProperty = new TBoxProperty(newPropName);
			properties.add(newProperty);
			return newProperty;
		} else {
			return getProperty(newPropName);
		}
	}

	public boolean containsClass(String className) {
		for (TBoxClass oneClass : classes) {
			if (oneClass.getName().equals(className)) {
				return true;
			}
		}
		return false;
	}

	public TBoxClass getClass(String className) {
		for (TBoxClass oneClass : classes) {
			if (oneClass.getName().equals(className)) {
				return oneClass;
			}
		}
		return null;
	}

	public boolean containsProperty(String propertyName) {
		for (TBoxProperty oneProp : properties) {
			if (oneProp.getName().equals(propertyName)) {
				return true;
			}
		}
		return false;
	}

	public TBoxProperty getProperty(String propertyName) {
		for (TBoxProperty oneProp : properties) {
			if (oneProp.getName().equals(propertyName)) {
				return oneProp;
			}
		}
		return null;
	}

	/**
	 * Creates thisClass \square_inclusion superClass relation, adding any
	 * missing class and adding one string into thisClass.super and
	 * superClass.sub lists
	 * 
	 * @param thisClassName
	 * @param superClassName
	 */
	public void addSuperClass(String thisClassName, String superClassName) {
		TBoxClass thisClass = getClass(thisClassName);
		TBoxClass superClass = getClass(superClassName);

		// add this class if not present
		if (thisClass == null) {
			thisClass = addClass(thisClassName);
		}

		// add this class if not present
		if (superClass == null) {
			superClass = addClass(superClassName);
		}

		thisClass.addSuperClass(superClassName);
		superClass.addSubClass(thisClassName);
	}

	public void addSuperProperty(String thisPropName, String superPropName) {
		TBoxProperty thisProp = getProperty(thisPropName);
		TBoxProperty superProp = getProperty(superPropName);

		// add this prop if not present
		if (thisProp == null) {
			thisProp = addProperty(thisPropName);
		}

		// add this class if not present
		if (superProp == null) {
			superProp = addProperty(superPropName);
		}

		thisProp.addSuperProp(superPropName);
		superProp.addSubProp(thisPropName);

	}

	public void addInverseProperty(String thisPropName, String invPropName) {
		TBoxProperty thisProp = getProperty(thisPropName);
		TBoxProperty invProp = getProperty(invPropName);

		// add this prop if not present
		if (thisProp == null) {
			thisProp = addProperty(thisPropName);
		}

		// add inv prop if not present
		if (invProp == null) {
			invProp = addProperty(invPropName);
		}

		thisProp.addInverseProp(invPropName);
		invProp.addInverseProp(thisPropName);

	}

	public void addDomain(String thisProp, String domain) {
		TBoxClass tempClass = getClass(domain);

		// add this class if not present
		if (tempClass == null) {
			tempClass = addClass(domain);
		}

		TBoxProperty tempProperty = getProperty(thisProp);
		// add this property if not present
		if (tempProperty == null) {
			tempProperty = addProperty(thisProp);
		}

		tempProperty.addDomain(tempClass);
		tempClass.setIsDomainOf(tempProperty);
	}

	public void addRange(String thisProp, String range) {
		TBoxClass tempClass = getClass(range);

		// add this class if not present
		if (tempClass == null) {
			tempClass = addClass(range);
		}

		TBoxProperty tempProperty = getProperty(thisProp);
		// add this property if not present
		if (tempProperty == null) {
			tempProperty = addProperty(thisProp);
		}

		tempProperty.addRange(tempClass);
		tempClass.setIsRangeOf(tempProperty);
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("\nTBox:");
		if (classes == null || classes.size() == 0) {
			sb.append("\nClasses[0]:\n");
		} else {
			sb.append(String.format("\nClasses[%s]:\n\t", classes.size()));
			for (TBoxClass oneClass : classes) {
				sb.append(oneClass.toString());
				sb.append("\n\t");
			}
		}

		if (properties == null || properties.size() == 0) {
			sb.append("\nProperties[0]:\n");
		} else {
			sb.append(String.format("\nProperties[%s]:\n\t", properties.size()));
			for (TBoxProperty oneProp : properties) {
				sb.append(oneProp.toString());
				sb.append("\n\t");
			}
		}
		return sb.toString();
	}

}